package cn.yueranzs.system.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.poi.excel.ExcelWriter;
import cn.yueranzs.handler.BusinessException;
import cn.yueranzs.response.ResultCode;
import cn.yueranzs.response.ResultPage;
import cn.yueranzs.system.mapper.DepartmentMapper;
import cn.yueranzs.system.pojo.Department;
import cn.yueranzs.system.service.DepartmentService;
import cn.yueranzs.utils.PaginationUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author yueranzs
 * @since 2021-11-09
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements DepartmentService {

    @Resource
    private DepartmentMapper departmentMapper;

    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public ResultPage findDeptAndCount(Department department, Page page) {
        Page<JSONObject> deptAndCount = departmentMapper.findDeptAndCount(department,page);
        return new ResultPage(deptAndCount.getTotal(),deptAndCount.getRecords());
    }

    /**
     * 添加部门
     *
     * @param department
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void saveDepartment(Department department) {
        department.setCreateTime(DateUtil.date());
        department.setDelflag(ResultCode.NODELETE.getCode());
        Department findDept = find(department);
        if (ObjectUtil.isNotNull(findDept)) {
            throw new BusinessException(ResultCode.DEPARTMENT_ALREADY_EXIST.getCode(),ResultCode.DEPARTMENT_ALREADY_EXIST.getMessage());
        }
        save(department);
    }

    /**
     * 修改部门
     *
     * @param department
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void updateDepartment(Department department) {
        department.setModifiedTime(DateUtil.date());
        Department findDept = find(department);
        //根据部门名查出有此部门并且不是自己则抛出已有部门名存在
        if (ObjectUtil.isNotNull(findDept) && !ObjectUtil.equals(findDept.getId(),department.getId())) {
            throw new BusinessException(ResultCode.DEPARTMENT_ALREADY_EXIST.getCode(),ResultCode.DEPARTMENT_ALREADY_EXIST.getMessage());
        }
        updateById(department);
    }

    /**
     * 导出部门
     *
     * @param response
     * @param department
     */
    @Transactional(propagation = Propagation.SUPPORTS,rollbackFor = Exception.class)
    @Override
    public void excelDeptList(HttpServletResponse response, Department department) {
        //初始化时定义表名
        ExcelWriter writer = new ExcelWriter(true, "部门列表");
        //自定义标题别名
        Map<String, String> mapZhu = MapUtil.newHashMap(true);
        mapZhu.put("id", "编号");
        mapZhu.put("name", "部门名称");
        mapZhu.put("phone", "系办公电话");
        mapZhu.put("address", "系办公地址");
        mapZhu.put("deptCount", "部门人数");
        mapZhu.forEach(writer::addHeaderAlias);
        Page page = PaginationUtil.getNewPage(1, -1);
        Page<JSONObject> deptPage = departmentMapper.findDeptAndCount(department, page);
        writer.write(deptPage.getRecords(), true);
        // 设置所有列宽
        writer.setColumnWidth(-1, 20);
        //写出xlsx
        ServletOutputStream out = null;
        try {
            //response为HttpServletResponse对象
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("部门列表", "UTF8") + ".xlsx");
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            writer.flush(out, true);
            writer.close();
            IoUtil.close(out);
        }
    }

    /**
     * 删除部门
     *
     * @param id
     */
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    @Override
    public void deleteDepartment(Long id) {
        Department department = getById(id);
        department.setModifiedTime(DateUtil.date());
        department.setDelflag(ResultCode.DELETE.getCode());
        updateById(department);
    }

    private Department find(Department department){
        return getOne(new QueryWrapper<Department>().lambda()
                .select(Department::getId, Department::getName)
                .eq(Department::getDelflag, ResultCode.NODELETE.getCode())
                .eq(Department::getName, department.getName())
        );
    }
}
